#include "InetAddress.h"

using namespace tmms::network;

void InetAddress::GetIpAndPort(const std::string &host,std::string &ip,std::string &port)
{
    auto pos  = host.find_first_of(':',0);
    if(pos!=std::string::npos)
    {
        ip = host.substr(0,pos);
        port = host.substr(pos+1);
        std::cout<<"hhh"<<ip <<"jjj"<<port<<std::endl;
    }
    else{ 
       ip =  host;
    }
}

InetAddress::InetAddress(const std::string &ip,uint16_t port,bool bv6 )
:addr_(ip),port_(std::to_string(port)),is_ipv6_(bv6)
{

}

InetAddress::InetAddress(const std::string &host,bool is_v6)
{
    GetIpAndPort(host,addr_, port_);
    
    is_ipv6_ = is_v6;
}

void InetAddress::SetHost(const std::string &host)
{
    GetIpAndPort(host,addr_, port_);
}
void InetAddress::SetAddr(const std::string &in_addr)
{
    addr_ = in_addr; //这有构造函数才可以使用初始化列表
}

void InetAddress::SetPort(uint16_t port)
{
    port_ = std::to_string(port);
}

void InetAddress::SetIsIPV6(bool is_v6)
{
    is_ipv6_ = is_v6;
}

 const std::string& InetAddress::IP() const
 {
    return addr_;
 }

uint32_t InetAddress::IPV4(const char* ip)const // 返回整形表示的地址
 {
    struct sockaddr_in addr_in ;
    memset(&addr_in,0x00,sizeof(struct sockaddr_in)); //清零

    //开始赋值
    addr_in.sin_family = AF_INET;
    addr_in.sin_port = 0;
    if(::inet_pton(AF_INET,ip,&addr_in.sin_addr)<0)
    {
        std::cout<<"报错了ipv4赋值不了"<<std::endl;
    }
    
    return  ntohl(addr_in.sin_addr.s_addr);
 }

std::string InetAddress::ToIpPort()const
 {
    std::stringstream ss;
    ss<<addr_<<":"<<port_;
    return ss.str();
 }
uint16_t InetAddress::Port() const
 {
    return std::atoi(port_.c_str());
 }
void InetAddress::GetSockAddr(struct sockaddr *saddr) const
 {
    if(is_ipv6_)
    {
        struct sockaddr_in6 * addr_in6 = ( sockaddr_in6 *) saddr;
        memset(addr_in6,0x00,sizeof(struct  sockaddr_in6) );

        addr_in6->sin6_family = AF_INET6;
        addr_in6->sin6_port = htons(std::atoi(port_.c_str()));
        if(::inet_pton(AF_INET6,addr_.c_str(),&addr_in6->sin6_addr)<0)
        {

        }
        return ;
    }

    struct sockaddr_in * addr_in = ( sockaddr_in *) saddr;
    memset(addr_in,0x00,sizeof(struct  sockaddr_in) );
    addr_in->sin_family = AF_INET;
    addr_in->sin_port = htons(std::atoi(port_.c_str()));
    if(::inet_pton(AF_INET,addr_.c_str(),&addr_in->sin_addr)<0)
    {

    }

 }

bool InetAddress::IsIpV6() const 
 {
    return is_ipv6_;
 }
bool InetAddress::IsWanIp()const 
 { //是不是广域网的地址
    uint32_t a_start = IPV4("10.0.0.0");
    uint32_t a_end = IPV4("10.255.255.255");

    uint32_t b_start = IPV4("172.16.0.0");
    uint32_t b_end = IPV4("172.31.255.255");

    uint32_t c_start = IPV4("192.168.0.0");
    uint32_t c_end = IPV4("192.168.255.255");

    uint32_t ip = IPV4();
    bool is_a = ip>=a_start && ip<=a_end;
    bool is_b = ip>=b_start && ip<=b_end;
    bool is_c = ip>=c_start && ip<=c_end;

    return !is_a&&!is_b&&!is_c&&ip!=INADDR_LOOPBACK;
 }
bool InetAddress::IsLanIp () const
 {//是不是局域网
      uint32_t a_start = IPV4("10.0.0.0");
    uint32_t a_end = IPV4("10.255.255.255");

    uint32_t b_start = IPV4("172.16.0.0");
    uint32_t b_end = IPV4("172.31.255.255");

    uint32_t c_start = IPV4("192.168.0.0");
    uint32_t c_end = IPV4("192.168.255.255");

    uint32_t ip = IPV4();
    bool is_a = ip>=a_start && ip<=a_end;
    bool is_b = ip>=b_start && ip<=b_end;
    bool is_c = ip>=c_start && ip<=c_end;

    return is_a||is_b||is_c;
 }
bool InetAddress::IsLoopbackIp() const
 { //判断是不是回路地址
    return addr_ == "127.0.0.1";
 }

uint32_t InetAddress::IPV4() const
{
    in_addr binary_addr;
    if (inet_pton(AF_INET, addr_.c_str(), &binary_addr) != 1) {
        // 转换失败处理
        return 0; // 或使用自定义错误处理
    }
    return binary_addr.s_addr;
}
